<?php

namespace app\admin\controller\community\project;

use app\common\controller\Backend;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 项目课程安排预置管理
 *
 * @icon fa fa-calendar
 */
class Schedule extends Backend
{
    /**
     * Schedule模型对象
     * @var \app\admin\model\community\project\Schedule
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\community\project\Schedule;
        $this->view->assign("statusList", $this->model->getStatusList());
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    /**
     * 查看
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            
            // 定义允许排序的字段
            $sortFields = ['id', 'project_name', 'school_name', 'course_name', 'day_of_week', 'start_time', 'end_time', 'createtime', 'updatetime'];
            // 定义允许搜索的字段
            $searchFields = ['project_name', 'school_name', 'course_name', 'day_of_week', 'community_name'];
            
            list($where, $sort, $order, $offset, $limit) = $this->buildparams($sortFields, $searchFields);
            
            // 初始化查询对象
            $prefix = config('database.prefix');
            $tableName = $prefix . 'community_project_schedule';
            $list = $this->model->alias('p')
                ->field('p.*, c.name')
                ->join($prefix . 'community c', 'p.community_id = c.id', 'LEFT');
            
            // 处理快速搜索
            $search = $this->request->get('search');
            if (!empty($search)) {
                // 快捷搜索框直接搜索多个字段
                $list->where(function ($query) use ($search) {
                    $query->where('p.project_name', 'like', '%' . $search . '%')
                          ->whereOr('p.school_name', 'like', '%' . $search . '%')
                          ->whereOr('p.course_name', 'like', '%' . $search . '%')
                          ->whereOr('c.name', 'like', '%' . $search . '%');
                });
            }
            
            // 处理高级搜索参数
            $filter = $this->request->get('filter', '');
            $op = $this->request->get('op', '');
            
            if ($filter && $op) {
                $filter = (array)json_decode($filter, true);
                $op = (array)json_decode($op, true);
                foreach ($filter as $key => $val) {
                    if ($val) {
                        $operator = isset($op[$key]) ? $op[$key] : 'like';
                        if ($operator == 'like') {
                            $list->where($key, 'like', "%{$val}%");
                        } else {
                            $list->where($key, $operator, $val);
                        }
                    }
                }
            }
            
            // 根据用户组限制查看权限
            $user = $this->auth->getUserInfo();
            if ($user['group_id'] == 8) {
                // 如果是社区管理员，只能查看自己社区的数据
                $list = $list->where('p.community_id', '=', $user['community_id']);
            }
            
            // 排序处理
            if ($sort && $order) {
                // 处理排序字段的表前缀
                $sort = str_replace('schedule.', '', $sort);
                switch ($sort) {
                    case 'id':
                    case 'project_name':
                    case 'school_name':
                    case 'course_name':
                    case 'day_of_week':
                    case 'start_time':
                    case 'end_time':
                    case 'createtime':
                    case 'updatetime':
                    case 'status':
                    case 'weigh':
                        $sort = 'p.' . $sort;
                        break;
                    case 'community_name':
                        $sort = 'c.name';
                        break;
                }
                $list->order($sort, $order);
            }
            
            // 打印SQL语句，用于调试
            // echo $list->fetchSql(true)->select();
            
            $total = $list->count();
            $list = $list->limit($offset, $limit)->select();
            
            // 将模型集合转换为数组
            $list = collection($list)->toArray();
            
            // 处理列表数据
            foreach ($list as &$row) {
                // 已经通过JOIN关联了社区表，直接使用关联结果
                $row['community_name'] = $row['name'] ?? '';
            }
            unset($row);
            
            $result = ["total" => $total, "rows" => $list];
            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 添加
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);

                if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
                    $params[$this->dataLimitField] = $this->auth->id;
                }
                
                // 检查是否存在冲突的课程安排
                $conflict = $this->checkScheduleConflict($params);
                if ($conflict) {
                    $this->error('该时间段已有课程安排，请选择其他时间');
                }
                
                $result = false;
                Db::startTrans();
                try {
                    // 是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
                        $this->model->validateFailException(true)->validate($validate);
                    }
                    $result = $this->model->allowField(true)->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were inserted'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        
        // 获取社区列表
        $communityList = Db::name('fa_community')->field('id, name')->select();
        $this->view->assign('communityList', $communityList);
        
        // 获取当前用户所属社区
        $user = $this->auth->getUserInfo();
        $community_id = $user['community_id'] ?? 0;
        $this->view->assign('community_id', $community_id);
        
        // 星期选项
        $weekdayList = [
            '1' => '周一',
            '2' => '周二',
            '3' => '周三',
            '4' => '周四',
            '5' => '周五',
            '6' => '周六',
            '7' => '周日'
        ];
        $this->view->assign('weekdayList', $weekdayList);
        
        return $this->view->fetch();
    }

    /**
     * 编辑
     */
    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                $params = $this->preExcludeFields($params);
                
                // 检查是否存在冲突的课程安排（排除当前记录）
                $conflict = $this->checkScheduleConflict($params, $ids);
                if ($conflict) {
                    $this->error('该时间段已有课程安排，请选择其他时间');
                }
                
                $result = false;
                Db::startTrans();
                try {
                    // 是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
                        $row->validateFailException(true)->validate($validate);
                    }
                    $result = $row->allowField(true)->save($params);
                    Db::commit();
                } catch (ValidateException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
                if ($result !== false) {
                    $this->success();
                } else {
                    $this->error(__('No rows were updated'));
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        
        // 获取社区列表
        $communityList = Db::name('fa_community')->field('id, name')->select();
        $this->view->assign('communityList', $communityList);
        
        // 星期选项
        $weekdayList = [
            '1' => '周一',
            '2' => '周二',
            '3' => '周三',
            '4' => '周四',
            '5' => '周五',
            '6' => '周六',
            '7' => '周日'
        ];
        $this->view->assign('weekdayList', $weekdayList);
        
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }
    
    /**
     * 检查课程安排冲突
     * @param array $params 课程安排参数
     * @param int $excludeId 排除的ID（用于编辑时）
     * @return bool 是否存在冲突
     */
    protected function checkScheduleConflict($params, $excludeId = null)
    {
        $query = $this->model->where([
            'community_id' => $params['community_id'],
            'day_of_week' => $params['day_of_week']
        ]);
        
        // 如果是编辑，排除当前记录
        if ($excludeId) {
            $query->where('id', '<>', $excludeId);
        }
        
        // 检查时间段是否冲突
        $conflict = $query->where(function ($query) use ($params) {
            // 新课程的开始时间在已有课程的时间段内
            $query->where('start_time', '<=', $params['start_time'])
                  ->where('end_time', '>', $params['start_time']);
        })->whereOr(function ($query) use ($params) {
            // 新课程的结束时间在已有课程的时间段内
            $query->where('start_time', '<', $params['end_time'])
                  ->where('end_time', '>=', $params['end_time']);
        })->whereOr(function ($query) use ($params) {
            // 新课程完全包含已有课程
            $query->where('start_time', '>=', $params['start_time'])
                  ->where('end_time', '<=', $params['end_time']);
        })->count();
        
        return $conflict > 0;
    }
}
